﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using BanaToys.InfoSys.Bll;
using BanaToys.InfoSys.Bol;
using Newtonsoft.Json;
using System.Web; //Server.MapPath上传文件物理路径

namespace BanaToys.InfoSys.Web.ApiCall.BanaWww
{
    /// <summary>
    /// API调用者
    /// </summary>
    public class Attach_ApiCall
    {
        private const string Url_Sync   = "v30/attach/attach.ashx?action=sync";
        private const string Url_Delete = "v30/attach/attach.ashx?action=delete";
        private const string Url_List   = "v30/attach/attach.ashx?action=list";
        private const string Url_Detail = "v30/attach/attach.ashx?action=detail";

        #region 1.同步,若是新增则默认上架

        /// <summary>
        /// 同步并上架显示
        /// </summary>
        /// <param name="i_attach"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool Sync(i_attach_item i_attach, out string message)
        {
            //
            message = null;

            //
            i_attach_item item = i_attach;
            q_attach_sync sync = new q_attach_sync();
            sync.Item = item;

            string para_json = JsonConvert.SerializeObject(sync);

            //调用接口
            string url_full = API_Config.API_Url.TrimEnd('/') + "/" + Url_Sync.TrimStart('/');

            //header
            Dictionary<string, string> dictHeader = API_Config.GetHeaderAuth();

            //
            string json;
            string errorText;
            bool ok = HttpHelp.PostFunction(url_full, para_json, dictHeader, "POST", out json, out errorText);
            if (!ok)
            {
                message = "错误:" + errorText;
                return false;
            }

            //ZBug.Log(json);

            //解析JSON
            a_attach_sync sync_msg = null;
            try
            {
                sync_msg = JsonConvert.DeserializeObject<a_attach_sync>(json);
            }
            catch (Exception ex)
            {
                message = "解析服务端返回JSON失败:" + ex.Message;
                return false;
            }

            if (sync_msg == null)
            {
                message = "服务端返回空";
                return false;
            }

            //业务判断
            message = string.Format("{0}", sync_msg.errmsg);
            if (sync_msg.errcode != 0)
            {
                message = string.Format("api返回失败:{0}({1})", sync_msg.errmsg, sync_msg.errcode);
                return false;
            }

            //返回
            return true;
        }

        /// <summary>
        /// 本地文件(需上传后)
        /// </summary>
        /// <param name="attach">产品附件</param>
        /// <param name="uploaded">已api上传文件信息</param>
        /// <returns></returns>
        private static i_attach_item convert_attach_to_i(BnProductAttach attach, a_upload uploaded)
        {
            if (attach == null)
            {
                return null;
            }

            if (attach.FFileUrlIsAbsolute)
            {
                //仅本地文件,需先上传
                return null;
            }

            if (attach.ParentFProductGuidBo == null)
            {
                BnProduct p = new BnProductBll().SysGet(attach.FProductGuid);
                if (p == null)
                {
                    return null;
                }
                attach.ParentFProductGuidBo = p;
            }

            i_attach_item item = new i_attach_item();
            item.FRowGuid = attach.FRowGuid.ToString().Trim('{', '}').ToLower();
            item.FAttachCategory = "Product";//attach.FAttachType;
            item.FAttachGuid = attach.FProductGuid.ToString().Trim('{','}');
            item.FAttachCode = attach.ParentFProductGuidBo.FBarcode;
            item.FOrderNo = attach.FSortNumber;
            item.FFileType = attach.FAttachType;
            item.FRemark = attach.FAttachRemarks;
            item.FChannelName = attach.FAttachChannel;
            //item.FFileDetailTextOCR = attach.;
            //item.FIsDisabled = attach.FIsDisabled;

            //需要先上传文件
            if (uploaded != null)
            {
                item.FFileUrlIsAbsolute = false; //仅本地文件,需先上传
                item.FFileUrl = uploaded.uploaded_url;//"product/2023_03/997040003__20230308_101854669.jpg";
                item.FFileSizeByte = uploaded.FileSizeByte;//88731;
                item.FFileMD5 = uploaded.FileMD5;//"f636bd5cd3ffff29cdba6ef89b3e3b5a";
                item.FFileOriginalName = uploaded.FileOriginalName;//"997040003.jpg";
            }

            //
            return item;
        }

        /// <summary>
        /// 远程绝对网址
        /// </summary>
        /// <param name="attach">产品附件</param>
        /// <returns></returns>
        private static i_attach_item convert_attach_to_i(BnProductAttach attach)
        {
            if (attach == null)
            {
                return null;
            }

            if (!attach.FFileUrlIsAbsolute)
            {
                //仅远程文件,绝对网址地址
                return null;
            }

            if (attach.ParentFProductGuidBo == null)
            {
                BnProduct p = new BnProductBll().SysGet(attach.FProductGuid);
                if (p == null)
                {
                    return null;
                }
                attach.ParentFProductGuidBo = p;
            }

            i_attach_item item = new i_attach_item();
            item.FRowGuid = attach.FRowGuid.ToString().Trim('{', '}').ToLower();
            item.FAttachCategory = "Product";//attach.FAttachType;
            item.FAttachGuid = attach.FProductGuid.ToString().Trim('{', '}');
            item.FAttachCode = attach.ParentFProductGuidBo.FBarcode;
            item.FOrderNo = attach.FSortNumber;
            item.FFileType = attach.FAttachType;
            item.FRemark = attach.FAttachRemarks;
            item.FChannelName = attach.FAttachChannel;
            //item.FFileDetailTextOCR = attach.;
            //item.FIsDisabled = attach.FIsDisabled;

            //绝对地址
            //if (uploaded != null)
            //{
            item.FFileUrlIsAbsolute = true; //仅远程文件,绝对网址地址
            item.FFileUrl = attach.FFileUrl;           //"https://www.abc.com/static/test.jpg"
            item.FFileSizeByte = attach.FFileByteSize; //88731;
            item.FFileMD5 = attach.FFileMD5;           //"f636bd5cd3ffff29cdba6ef89b3e3b5a";
            item.FFileOriginalName = "";               //"997040003.jpg";
            //}

            //
            return item;
        }

        /// <summary>
        /// 本地文件(需上传后)
        /// </summary>
        /// <param name="product">产品</param>
        /// <param name="uploaded">已api上传文件信息</param>
        /// <returns></returns>
        private static i_attach_item convert_attach_to_i(BnProduct product, a_upload uploaded)
        {
            if (product == null)
            {
                return null;
            }

            i_attach_item item = new i_attach_item();
            item.FRowGuid = product.FRowGuid.ToString().Trim('{', '}').ToLower();
            item.FAttachCategory = "Product";//attach.FAttachType;
            item.FAttachGuid = product.FRowGuid.ToString().Trim('{', '}');
            item.FAttachCode = product.FBarcode;
            item.FOrderNo = 999;
            item.FFileType = "Image";
            item.FRemark = string.Empty;
            //item.FChannelName = string.Empty;//"first";//主图
            //item.FFileDetailTextOCR = attach.;
            //item.FIsDisabled = attach.FIsDisabled;

            //需要先上传文件
            if (uploaded != null)
            {
                item.FFileUrlIsAbsolute = false; //仅本地文件,需先上传
                item.FFileUrl = uploaded.uploaded_url;//"product/2023_03/997040003__20230308_101854669.jpg";
                item.FFileSizeByte = uploaded.FileSizeByte;//88731;
                item.FFileMD5 = uploaded.FileMD5;//"f636bd5cd3ffff29cdba6ef89b3e3b5a";
                item.FFileOriginalName = uploaded.FileOriginalName;//"997040003.jpg";
            }

            //
            return item;
        }

        /// <summary>
        /// 本地文件(需上传后)
        /// </summary>
        /// <param name="brand">品牌</param>
        /// <param name="uploaded">已api上传文件信息</param>
        /// <returns></returns>
        private static i_attach_item convert_attach_to_i(BnBrand brand, a_upload uploaded)
        {
            if (brand == null)
            {
                return null;
            }

            //if (brand.FFileUrlIsAbsolute)
            //{
            //    //仅本地文件,需先上传
            //    return null;
            //}

            //if (attach.ParentFProductGuidBo == null)
            //{
            //    BnProduct p = new BnProductBll().SysGet(attach.FProductGuid);
            //    if (p == null)
            //    {
            //        return null;
            //    }
            //    attach.ParentFProductGuidBo = p;
            //}

            i_attach_item item = new i_attach_item();
            item.FRowGuid = brand.FRowGuid.ToString().Trim('{', '}').ToLower();
            item.FAttachCategory = "Brand";//attach.FAttachType;
            item.FAttachGuid = brand.FRowGuid.ToString().Trim('{', '}');
            item.FAttachCode = brand.FCode;
            item.FOrderNo = brand.FOrderNo;
            item.FFileType = "Image";
            item.FRemark = brand.FRemarks;
            item.FChannelName = string.Empty;//主图辅图详情图
            //item.FFileDetailTextOCR = attach.;
            //item.FIsDisabled = attach.FIsDisabled;

            //需要先上传文件
            if (uploaded != null)
            {
                item.FFileUrlIsAbsolute = false; //仅本地文件,需先上传
                item.FFileUrl = uploaded.uploaded_url;//"product/2023_03/997040003__20230308_101854669.jpg";
                item.FFileSizeByte = uploaded.FileSizeByte;//88731;
                item.FFileMD5 = uploaded.FileMD5;//"f636bd5cd3ffff29cdba6ef89b3e3b5a";
                item.FFileOriginalName = uploaded.FileOriginalName;//"997040003.jpg";
            }

            //
            return item;
        }

        /// <summary>
        /// 重要代码
        /// </summary>
        private void Test_Sync()
        {
            //产品
            string barcode = "901010001";
            BnProduct bp = new BnProductBll().SysGet(barcode);
            if (bp == null)
            {
                Debug.WriteLine("没有这个条码:" + barcode + ".");
                return;
            }
            //Console.WriteLine(bp.ToMemberString());

            //产品附件
            StringBuilder sb = new StringBuilder();
            List<BnProductAttach> attachs = new BnProductAttachBll().UserGetListByProduct(bp.FRowGuid, null);// AttachType.Image
            int count = attachs.Count;
            int success = 0;
            for (int i = 0; i < count; i++)
            {
                BnProductAttach attach = attachs[i];
                int idx_no = i + 1;

                //
                if (attach == null)
                {
                    sb.AppendLine(string.Format("第{0}个为空", idx_no));
                    continue;
                }
                string url = string.Format("{0}", attach.FFileUrl).Trim();
                if (url.Length == 0)
                {
                    sb.AppendLine(string.Format("第{0}个没有文件路径或地址", idx_no));
                    continue;
                }

                //
                i_attach_item item = null;

                //本地文件还是远程文件
                if (!attach.FFileUrlIsAbsolute)
                {
                    //本地文件,相对地址
                    string filePathName = @"E:\Dev_Temp\database_pic" + "\\" + url.Replace("product2012/", string.Empty).TrimStart('/','\\').Replace("/","\\");
                    if (!File.Exists(filePathName))
                    {
                        sb.AppendLine(string.Format("第{0}个本地文件不存在", idx_no));
                        continue;
                    }

                    //先上传
                    i_upload_formdata form = new i_upload_formdata();//test
                    form.module = "Product";
                    form.pkid = barcode;
                    form.thumb = false;
                    form.file_physics_path_name = filePathName;

                    a_upload upload_a;
                    string upload_message;
                    bool uploadOk = Upload_ApiCall.UploadFile(form, out upload_a, out upload_message);
                    if (!uploadOk)
                    {
                        sb.AppendLine(string.Format("第{0}个上传失败", idx_no));
                        continue;
                    }
                    if (upload_a == null)
                    {
                        sb.AppendLine(string.Format("第{0}个上传返回对象为空:{1}", idx_no, upload_message));
                        continue;
                    }

                    //同步转换i_attach_item
                    item = convert_attach_to_i(attach, upload_a);
                    if (item == null)
                    {
                        sb.AppendLine(string.Format("第{0}个转换为空", idx_no));
                        continue;
                    }
                }
                else
                {
                    //远程文件,绝对地址


                    //同步转换i_attach_item
                    item = convert_attach_to_i(attach);
                    if (item == null)
                    {
                        sb.AppendLine(string.Format("第{0}个转换为空", idx_no));
                        continue;
                    }
                }

                //上传完成
                string sync_message;
                bool call_ok = Sync(item, out sync_message);
                //Console.WriteLine("是否成功={0},返回={1}", call_ok, message);
                if (!call_ok)
                {
                    sb.AppendLine(string.Format("第{0}个提交附件同步失败:{1}", idx_no, sync_message));
                    continue;
                }

                //最终完成一个附件
                success += 1;
                sb.AppendLine(string.Format("{0}第{1}个附件同步成功:{2}", barcode, idx_no, sync_message));
            } //for

            //
            string s = string.Format(
                "同步{0}的{1}个附件结束,共成功{2}个\n\n{3}", 
                barcode, 
                count,
                success,
                sb.ToString()
                );
            Debug.WriteLine(s);
        }

        #endregion

        #region 1.2.同步附件db,上传文件file

        /// <summary>
        /// 上传产品附件(包含上传文件),只要上传一个成功就代表成功
        /// </summary>
        /// <param name="barcode"></param>
        /// <param name="app_upload_dir">上传文件主虚拟目录</param>
        /// <param name="row_count"></param>
        /// <param name="row_success"></param>
        /// <param name="row_fail"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool? Sync_ProductAttach(string barcode, string app_upload_dir,
            out int row_count, out int row_success, out int row_fail, out string message)
        {
            //
            const string MODULE = "Product";

            //
            row_count = 0; //总有效附件行数
            row_success = 0; //成功行数
            row_fail = 0; //失败行数
            message = null;

            //产品
            BnProduct bp = new BnProductBll().SysGet(barcode);
            if (bp == null)
            {
                message = "没有这个产品条码:" + barcode + ".";
                Debug.WriteLine(message);
                return false;
            }
            //Console.WriteLine(bp.ToMemberString());
            //ZBug.Log(bp.ToMemberString());

            //上传主目录
            string app_upload_dir_url = string.Format("{0}", app_upload_dir).Trim('~', '/', '\\').Replace('\\', '/');
            ZBug.Log("app_upload_dir_url=", app_upload_dir_url);

            //文件主目录存在
            //file_dir_physics_path = string.Format("{0}", file_dir_physics_path);
            //if (file_dir_physics_path.Length == 0)
            //{
            //    message = "文件所在主目录为空";
            //    Debug.WriteLine(message);
            //    return false;
            //}
            //if (!Directory.Exists(file_dir_physics_path))
            //{
            //    message = "文件所在文件主目录不存在";
            //    Debug.WriteLine(message);
            //    return false;
            //}

            //产品附件
            StringBuilder sb = new StringBuilder();
            List<BnProductAttach> attachs = new BnProductAttachBll().UserGetListByProduct(bp.FRowGuid, null);
            row_count = attachs.Count; //TODO:内部系统主图要加入附件行
            const string PRODUCT_URL_OLD = "../database_pic/";
            const string PRODUCT_URL_NEW = "product2012/";
            for (int i = 0; i < row_count; i++)
            {
                BnProductAttach attach = attachs[i];
                int idx_no = i + 1;

                //
                if (attach == null)
                {
                    sb.AppendLine(string.Format("第{0}个为空", idx_no));
                    row_fail += 1;
                    continue;
                }
                string url = string.Format("{0}", attach.FFileUrl).Trim();

                ZBug.Log("barcode = " + barcode, "idx = " + i.ToString(), "url = " + url);

                if (url.Length == 0)
                {
                    sb.AppendLine(string.Format("第{0}个没有文件路径或地址", idx_no));
                    row_fail += 1;
                    continue;
                }

                //产品上传目录“../database_pic/”的处理
                if (url.StartsWith(PRODUCT_URL_OLD))
                {
                    url = url.Substring(PRODUCT_URL_OLD.Length); //去除老的
                    url = PRODUCT_URL_NEW + url; //加上新的
                }

                //
                i_attach_item item = null;

                //本地文件还是远程文件
                if (!attach.FFileUrlIsAbsolute)
                {
                    //本地文件,相对地址
                    //string filePathName = @"E:\Dev_Temp\database_pic" + "\\" + url.Replace("product2012/", string.Empty).TrimStart('/', '\\').Replace("/", "\\");
                    //string filePathName = file_dir_physics_path.TrimEnd('\\') + "\\" + url.TrimStart('/', '\\').Replace("/", "\\");
                    string full_url = string.Format("~/{0}/{1}", app_upload_dir_url, url.TrimStart('/'));
                    ZBug.Log("full_url=", full_url);
                    string filePathName = HttpContext.Current.Server.MapPath(full_url);
                    ZBug.Log("MapPath=", filePathName);
                    if (!File.Exists(filePathName))
                    {
                        sb.AppendLine(string.Format("第{0}个本地文件不存在", idx_no));
                        ZBug.Log(barcode, "本地文件不存在=", filePathName);
                        row_fail += 1;
                        continue;
                    }

                    #region 上传文件

                    //先上传
                    i_upload_formdata form = new i_upload_formdata(); //test
                    form.module = MODULE;
                    form.pkid = barcode;
                    form.thumb = false;
                    form.file_physics_path_name = filePathName;

                    a_upload upload_a;
                    string upload_message;
                    bool uploadOk = Upload_ApiCall.UploadFile(form, out upload_a, out upload_message);
                    if (!uploadOk)
                    {
                        sb.AppendLine(string.Format("第{0}个上传失败", idx_no));
                        row_fail += 1;
                        continue;
                    }
                    if (upload_a == null)
                    {
                        sb.AppendLine(string.Format("第{0}个上传返回对象为空:{1}", idx_no, upload_message));
                        row_fail += 1;
                        continue;
                    }

                    #endregion

                    //同步转换i_attach_item
                    item = convert_attach_to_i(attach, upload_a);
                    if (item == null)
                    {
                        sb.AppendLine(string.Format("第{0}个附件同步转换为空", idx_no));
                        row_fail += 1;
                        continue;
                    }
                }
                else
                {
                    //远程文件,绝对地址

                    //同步转换i_attach_item
                    item = convert_attach_to_i(attach);
                    if (item == null)
                    {
                        sb.AppendLine(string.Format("第{0}个附件同步转换为空", idx_no));
                        row_fail += 1;
                        continue;
                    }
                }

                //上传完成,同步附件信息
                string sync_message;
                bool call_ok = Sync(item, out sync_message);
                if (!call_ok)
                {
                    sb.AppendLine(string.Format("第{0}个提交附件同步失败:{1}", idx_no, sync_message));
                    row_fail += 1;
                    continue;
                }

                //最终完成一个附件
                row_success += 1;
                sb.AppendLine(string.Format("{0}第{1}个附件同步成功:{2}", barcode, idx_no, sync_message));
            } //for

            //返回(只要一个同步成功就代表成功完成)
            message = sb.ToString();
            ZBug.Log(message);
            if (row_count > 0 && row_success == row_count) return true; //全部成功
            if (row_count > 0 && row_fail == row_count) return false; //全部失败
            return null;
        }

        /// <summary>
        /// 上传产品老主图一个(包含上传文件)
        /// </summary>
        /// <param name="product">产品</param>
        /// <param name="app_upload_dir">上传文件主虚拟目录</param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool Sync_Product_MainImage(BnProduct product, string app_upload_dir, out string message)
        {
            //
            const string MODULE = "Product";
            message = null;

            //产品
            if (product == null)
            {
                message = "产品为空";
                Debug.WriteLine(message);
                return false;
            }
            string barcode = product.FBarcode;


            //上传主目录
            string app_upload_dir_url = string.Format("{0}", app_upload_dir).Trim('~', '/', '\\').Replace('\\', '/');
            ZBug.Log("app_upload_dir_url=", app_upload_dir_url);


            //产品老主图
            string url = string.Format("{0}", product.FPicPath).Trim();
            
            //产品上传目录“../database_pic/”的处理
            const string PRODUCT_URL_OLD = "../database_pic/";
            const string PRODUCT_URL_NEW = "product2012/";
            if (url.StartsWith(PRODUCT_URL_OLD))
            {
                url = url.Substring(PRODUCT_URL_OLD.Length); //去除老的
                url = PRODUCT_URL_NEW + url; //加上新的
            }

            ZBug.Log("code = " + barcode, "url = " + url);
            if (url.Length == 0)
            {
                message = "没有文件路径或地址";
                //row_fail += 1;
                return false;
            }

            //
            i_attach_item item = null;

            #region 本地文件,相对地址

            //本地文件,相对地址
            string full_url = string.Format("~/{0}/{1}", app_upload_dir_url, url.TrimStart('/'));
            ZBug.Log("full_url=", full_url);
            string filePathName = HttpContext.Current.Server.MapPath(full_url);
            ZBug.Log("MapPath=", filePathName);
            if (!File.Exists(filePathName))
            {
                message = "本地文件不存在";
                ZBug.Log(barcode, "本地文件不存在=", filePathName);
                return false;
            }

            #region 上传文件

            //先上传
            i_upload_formdata form = new i_upload_formdata(); //test
            form.module = MODULE;
            form.pkid = barcode;
            form.thumb = false;
            form.file_physics_path_name = filePathName;

            a_upload upload_a;
            string upload_message;
            bool uploadOk = Upload_ApiCall.UploadFile(form, out upload_a, out upload_message);
            if (!uploadOk)
            {
                message = "上传失败:" + upload_message;
                return false;
            }
            if (upload_a == null)
            {
                message = string.Format("上传返回对象为空:{0}", upload_message);
                return false;
            }

            #endregion

            //同步转换i_attach_item
            item = convert_attach_to_i(product, upload_a);
            if (item == null)
            {
                message = "产品主图附件同步转换为空";
                return false;
            }

            #endregion

            //上传完成,同步附件信息
            string sync_message;
            bool call_ok = Sync(item, out sync_message);
            if (!call_ok)
            {
                message = string.Format("提交主图同步失败:{0}", sync_message);
                return false;
            }

            //最终完成一个附件
            message = string.Format("{0}产品主图同步成功:{1}", barcode, sync_message);
            return true;
        }

        /// <summary>
        /// 上传品牌附件(包含上传文件),只要上传一个成功就代表成功
        /// </summary>
        /// <param name="brand_code">品牌代码</param>
        /// <param name="app_upload_dir">上传文件主虚拟目录</param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool Sync_BrandAttach(string brand_code, string app_upload_dir,out string message)
        {
            //
            const string MODULE = "Brand";

            //
            //row_count = 0; //总有效附件行数
            //row_success = 0; //成功行数
            //row_fail = 0; //失败行数
            message = null;

            //品牌
            BnBrand brand_bo = new BnBrandBll().UserGetByCode(brand_code);
            if (brand_bo == null)
            {
                message = "没有这个品牌代码:" + brand_code + ".";
                Debug.WriteLine(message);
                return false;
            }

            //上传主目录
            string app_upload_dir_url = string.Format("{0}", app_upload_dir).Trim('~', '/', '\\').Replace('\\', '/');
            ZBug.Log("app_upload_dir_url=", app_upload_dir_url);

            //品牌附件
            //StringBuilder sb = new StringBuilder();
            //row_count = 1;//只有一个
            string url = string.Format("{0}", brand_bo.FBrandImageUrl).Trim();
            ZBug.Log("code = " + brand_code, "url = " + url);
            if (url.Length == 0)
            {
                message = "没有文件路径或地址";
                //row_fail += 1;
                return false;
            }

            //
            i_attach_item item = null;

            #region 本地文件,相对地址

            //本地文件,相对地址
            string full_url = string.Format("~/{0}/{1}", app_upload_dir_url, url.TrimStart('/'));
            ZBug.Log("full_url=", full_url);
            string filePathName = HttpContext.Current.Server.MapPath(full_url);
            ZBug.Log("MapPath=", filePathName);
            if (!File.Exists(filePathName))
            {
                message = "本地文件不存在";
                ZBug.Log(brand_code, "本地文件不存在=", filePathName);
                return false;
            }

            #region 上传文件

            //先上传
            i_upload_formdata form = new i_upload_formdata(); //test
            form.module = MODULE;
            form.pkid = brand_code;
            form.thumb = false;
            form.file_physics_path_name = filePathName;

            a_upload upload_a;
            string upload_message;
            bool uploadOk = Upload_ApiCall.UploadFile(form, out upload_a, out upload_message);
            if (!uploadOk)
            {
                message = "上传失败:" + upload_message;
                return false;
            }
            if (upload_a == null)
            {
                message = string.Format("上传返回对象为空:{0}", upload_message);
                return false;
            }

            #endregion

            //同步转换i_attach_item
            item = convert_attach_to_i(brand_bo, upload_a);
            if (item == null)
            {
                message = "附件同步转换为空";
                return false;
            }

            #endregion

            #region 远程文件,绝对地址
            //}
            //else
            //{
            //    //远程文件,绝对地址
            //    //同步转换i_attach_item
            //    item = convert_attach_to_i(attach);
            //    if (item == null)
            //    {
            //        sb.AppendLine(string.Format("第{0}个附件同步转换为空", idx_no));
            //        row_fail += 1;
            //        continue;
            //    }
            //}
            #endregion

            //上传完成,同步附件信息
            string sync_message;
            bool call_ok = Sync(item, out sync_message);
            if (!call_ok)
            {
                message = string.Format("提交附件同步失败:{0}", sync_message);
                return false;
            }

            //最终完成一个附件
            message = string.Format("{0}附件同步成功:{1}", brand_code, sync_message);
            return true;
        }

        #endregion

        #region 3.直接删除

        /// <summary>
        /// 
        /// </summary>
        /// <param name="q"></param>
        /// <param name="a"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool Delete(q_attach_delete q, out a_attach_delete a, out string message)
        {
            a = null;
            message = null;

            //
            if (q == null)
            {
                message = "请求参数对象为空";
                return false;
            }

            //json ------------------------------------------------------------
            string para_json = JsonConvert.SerializeObject(q);

            //调用接口
            string url_full = API_Config.API_Url.TrimEnd('/') + "/" + Url_Delete.TrimStart('/');

            //header
            Dictionary<string, string> dictHeader = API_Config.GetHeaderAuth();

            //
            string json;
            string errorText;
            bool ok = HttpHelp.PostFunction(url_full, para_json, dictHeader, "POST", out json, out errorText);
            if (!ok)
            {
                message = "错误:" + errorText;
                return false;
            }

            //ZBug.Log(json);
            //Debug.WriteLine(json);

            //解析Json
            //a_attach_delete a = null;
            try
            {
                a = JsonConvert.DeserializeObject<a_attach_delete>(json);
            }
            catch (Exception ex)
            {
                message = "解析服务端返回JSON失败:" + ex.Message;
                return false;
            }
            if (a == null)
            {
                message = "服务端返回空";
                return false;
            }

            //解析业务
            if (a.errcode != 0)
            {
                message = string.Format("服务端返回失败:{0}({1})", a.errmsg, a.errcode);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void Test_Delete()
        {
            //请求参数,全部忽略
            q_attach_delete q = new q_attach_delete();
            q.FRowGuid = "ef20a5a2-8bb1-4afe-91e7-609c4da202bc";

            //接收响应数据
            a_attach_delete a;

            string message;
            bool call_ok = Delete(q, out a, out message);
            Debug.WriteLine(string.Format("是否成功={0},返回={1}", call_ok, message));
            if (call_ok && a != null)
            {
                Debug.WriteLine(Help.ObjectToString(a));
            }
        }

        #endregion

        #region 4.展示列表

        /// <summary>
        /// 默认页尺寸
        /// </summary>
        public const int PageSize = 10;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="q">请求q参数</param>
        /// <param name="list_ok">输出：响应a数据</param>
        /// <param name="message">输出：错误消息</param>
        /// <returns></returns>
        public static bool GetList(q_attach_list q, out a_attach_list list_ok, out string message)
        {
            list_ok = null;
            message = null;

            //
            if (q == null)
            {
                message = "请求参数对象为空";
                return false;
            }

            //json ------------------------------------------------------------
            string para_json = JsonConvert.SerializeObject(q);

            //调用接口
            string url_full = API_Config.API_Url.TrimEnd('/') + "/" + Url_List.TrimStart('/');

            //header
            Dictionary<string, string> dictHeader = API_Config.GetHeaderAuth();

            //
            string json;
            string errorText;
            bool ok = HttpHelp.PostFunction(url_full, para_json, dictHeader, "POST", out json, out errorText);
            if (!ok)
            {
                message = "错误:" + errorText;
                return false;
            }

            //ZBug.Log(json);
            //Debug.WriteLine(json);

            //解析Json
            a_attach_list list = null;
            try
            {
                list = JsonConvert.DeserializeObject<a_attach_list>(json);
            }
            catch (Exception ex)
            {
                message = "解析服务端返回JSON失败:" + ex.Message;
                return false;
            }
            if (list == null)
            {
                message = "服务端返回空";
                return false;
            }

            //解析业务
            if (list.errcode != 0)
            {
                message = string.Format("服务端返回失败:{0}({1})", list.errmsg, list.errcode);
                return false;
            }

            //return
            list_ok = list;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void Test_GetList()
        {
            //请求参数
            q_attach_list q = new q_attach_list();
            q.QCategory = "Product";
            q.QCode = "901010001";

            //接收响应数据
            a_attach_list a;

            string message;
            bool call_ok = GetList(q, out a, out message);
            Debug.WriteLine(string.Format("是否成功={0},返回={1}", call_ok, message));
            if (call_ok && a != null)
            {
                Debug.WriteLine(Help.ObjectToString(a));
                if (a.List != null)
                {
                    Debug.WriteLine("有" + a.List.Count + "个");
                }
            }
        }

        #endregion

        #region 5.展示详情

        /// <summary>
        /// 
        /// </summary>
        /// <param name="q">请求q参数</param>
        /// <param name="detail_ok">输出：响应a数据</param>
        /// <param name="message">输出：错误消息</param>
        /// <returns></returns>
        public static bool GetDetail(q_attach_detail q, out a_attach_detail detail_ok, out string message)
        {
            detail_ok = null;
            message = null;

            //
            if (q == null)
            {
                message = "请求参数对象为空";
                return false;
            }

            //json ------------------------------------------------------------
            string para_json = JsonConvert.SerializeObject(q);

            //调用接口
            string url_full = API_Config.API_Url.TrimEnd('/') + "/" + Url_Detail.TrimStart('/');

            //header
            Dictionary<string, string> dictHeader = API_Config.GetHeaderAuth();

            //
            string json;
            string errorText;
            bool ok = HttpHelp.PostFunction(url_full, para_json, dictHeader, "POST", out json, out errorText);
            if (!ok)
            {
                message = "错误:" + errorText;
                return false;
            }

            //ZBug.Log(json);
            //Debug.WriteLine(json);

            //解析Json
            a_attach_detail detail = null;
            try
            {
                detail = JsonConvert.DeserializeObject<a_attach_detail>(json);
            }
            catch (Exception ex)
            {
                message = "解析服务端返回JSON失败:" + ex.Message;
                return false;
            }
            if (detail == null)
            {
                message = "服务端返回空";
                return false;
            }

            //解析业务
            if (detail.errcode != 0)
            {
                message = string.Format("服务端返回失败:{0}({1})", detail.errmsg, detail.errcode);
                return false;
            }

            //return
            detail_ok = detail;
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void Test_GetDetail()
        {
            //请求参数
            q_attach_detail q = new q_attach_detail();
            q.FRowGuid = "fbed63c8-4c0c-4df5-bdab-90f00bb55497";

            //接收响应数据
            a_attach_detail a;

            string message;
            bool call_ok = GetDetail(q, out a, out message);
            Debug.WriteLine(string.Format("是否成功={0},返回={1}", call_ok, message));
            if (call_ok && a != null)
            {
                Debug.WriteLine(Help.ObjectToString(a));
                if (a.Item != null)
                {
                    Debug.WriteLine(Help.ObjectToString(a.Item));
                }
            }
        }

        #endregion

    }
}